package com.softserveinc.video;

import java.io.IOException;

import android.app.Activity;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnVideoSizeChangedListener;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import com.softserveinc.R;

public class VideoPlayerActivity extends Activity implements
		OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener,
		OnVideoSizeChangedListener, SurfaceHolder.Callback {

	private static final String TAG = VideoPlayerActivity.class.getSimpleName();

	private static final String DEFAULT_VIDEO = "/sdcard/TubeX/Leonberger skating!!.mp4";

	private int mVideoWidth;
	private int mVideoHeight;
	private MediaPlayer mMediaPlayer;
	private SurfaceView mPreview;
	private SurfaceHolder holder;
	private String path;
	private boolean mIsVideoSizeKnown = false;
	private boolean mIsVideoReadyToBePlayed = false;

	@Override
	public void onCreate(final Bundle icicle) {
		super.onCreate(icicle);
		setContentView(R.layout.player);
		mPreview = (SurfaceView) findViewById(R.id.surface);
		holder = mPreview.getHolder();
		holder.addCallback(this);
		holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

		path = getIntent().getDataString();
	}

	@Override
	public boolean onCreateOptionsMenu(final Menu menu) {
		getMenuInflater().inflate(R.menu.player_menu, menu);

		return true;
	}

	@Override
	public boolean onOptionsItemSelected(final MenuItem item) {
		switch (item.getItemId()) {
		case R.id.start:
			holder.setFixedSize(mVideoWidth, mVideoHeight);
			mMediaPlayer.start();
			return true;
		case R.id.stop:
			mMediaPlayer.stop();
			playVideo();
			holder.setFixedSize(mVideoWidth, mVideoHeight);
			mMediaPlayer.start();
			return true;
		case R.id.pause:
			mMediaPlayer.pause();
			return true;
		default:
			break;
		}
		return super.onOptionsItemSelected(item);
	}

	private void playVideo() {
		doCleanUp();
		try {
			if (path == null || path.equals("")) {
				path = DEFAULT_VIDEO;
			}

			initVideo();

		} catch (Exception e) {
			Log.e(TAG, "error: " + e.getMessage(), e);

			Intent intent = new Intent(Intent.ACTION_VIEW);
			intent.setData(Uri.parse(path));
			startActivity(intent);

			finish();
		}
	}

	private void initVideo() throws IOException {
		mMediaPlayer = new MediaPlayer();
		mMediaPlayer.setDataSource(path);
		mMediaPlayer.setDisplay(holder);
		mMediaPlayer.prepare();
		mMediaPlayer.setOnBufferingUpdateListener(this);
		mMediaPlayer.setOnCompletionListener(this);
		mMediaPlayer.setOnPreparedListener(this);
		mMediaPlayer.setOnVideoSizeChangedListener(this);
		mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
	}

	@Override
	public void onBufferingUpdate(final MediaPlayer arg0, final int percent) {
		Log.d(TAG, "onBufferingUpdate percent:" + percent);

	}

	@Override
	public void onCompletion(final MediaPlayer arg0) {
		Log.d(TAG, "onCompletion called");
	}

	@Override
	public void onVideoSizeChanged(final MediaPlayer mp, final int width,
			final int height) {
		Log.v(TAG, "onVideoSizeChanged called");
		if (width == 0 || height == 0) {
			Log.e(TAG, "invalid video width(" + width + ") or height(" + height
					+ ")");
			return;
		}
		mIsVideoSizeKnown = true;
		mVideoWidth = width;
		mVideoHeight = height;
		if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
			startVideoPlayback();
		}
	}

	@Override
	public void onPrepared(final MediaPlayer mediaplayer) {
		Log.d(TAG, "onPrepared called");
		mIsVideoReadyToBePlayed = true;
		if (mIsVideoReadyToBePlayed && mIsVideoSizeKnown) {
			startVideoPlayback();
		}
	}

	@Override
	public void surfaceChanged(final SurfaceHolder surfaceholder, final int i,
			final int j, final int k) {
		Log.d(TAG, "surfaceChanged called");

	}

	@Override
	public void surfaceDestroyed(final SurfaceHolder surfaceholder) {
		Log.d(TAG, "surfaceDestroyed called");
	}

	@Override
	public void surfaceCreated(final SurfaceHolder holder) {
		Log.d(TAG, "surfaceCreated called");
		playVideo();
	}

	@Override
	protected void onPause() {
		super.onPause();
		releaseMediaPlayer();
		doCleanUp();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		releaseMediaPlayer();
		doCleanUp();
	}

	private void releaseMediaPlayer() {
		if (mMediaPlayer != null) {
			mMediaPlayer.release();
			mMediaPlayer = null;
		}
	}

	private void doCleanUp() {
		mVideoWidth = 0;
		mVideoHeight = 0;
		mIsVideoReadyToBePlayed = false;
		mIsVideoSizeKnown = false;
	}

	private void startVideoPlayback() {
		Log.v(TAG, "startVideoPlayback");
		holder.setFixedSize(mVideoWidth, mVideoHeight);
		mMediaPlayer.start();
	}
}
